package com.zhaoyh.util;

import org.apache.commons.lang.StringUtils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;

public class DateUtil {

	public static long str2Long(String str, String pattern) {
		return str2Date(str, pattern).getTime();
	}

	public static Date str2Date(String str, String pattern) {
		if (StringUtils.isBlank(str))
			return null;

		Date date = null;
		try {
			SimpleDateFormat format = new SimpleDateFormat(pattern);
			date = format.parse(str);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return date;
	}


	public static String isWeekend(String date, String pattern) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(str2Date(date, pattern));

		if (cal.get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY) {
			return "周六";
		} else if (cal.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY) {
			return "周日";
		} else {
			return "";
		}
	}

	public static String isWeekend(Date date) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);

		if (cal.get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY) {
			return "周六";
		} else if (cal.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY) {
			return "周日";
		} else {
			return "";
		}
	}

	public static long getCurrentTime2Long() {
		return System.currentTimeMillis();
	}

	public static Date getCurrentTime2Date() {
		return new Date();
	}

	public static Date getNextMonthStartTime(Date time) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(time);

		calendar.set(Calendar.DAY_OF_MONTH, 1);
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);

		calendar.add(Calendar.MONTH, 1);
		return calendar.getTime();
	}

	public static Date getTodayStartTime() {
		Calendar todayStart = Calendar.getInstance();
		todayStart.set(Calendar.HOUR_OF_DAY, 0);
		todayStart.set(Calendar.MINUTE, 0);
		todayStart.set(Calendar.SECOND, 0);
		todayStart.set(Calendar.MILLISECOND, 0);
		return todayStart.getTime();
	}

	public static Date getStartTime(Date time) {
		Calendar todayStart = Calendar.getInstance();
		todayStart.setTime(time);
		todayStart.set(Calendar.HOUR_OF_DAY, 0);
		todayStart.set(Calendar.MINUTE, 0);
		todayStart.set(Calendar.SECOND, 0);
		todayStart.set(Calendar.MILLISECOND, 0);
		return todayStart.getTime();
	}

	public static Date getTodayEndTime() {
		Calendar todayEnd = Calendar.getInstance();
		todayEnd.set(Calendar.HOUR_OF_DAY, 23);
		todayEnd.set(Calendar.MINUTE, 59);
		todayEnd.set(Calendar.SECOND, 59);
		todayEnd.set(Calendar.MILLISECOND, 999);
		return todayEnd.getTime();
	}

	public static Date getYesterdayStartTime() {
		return new Date(getTodayStartTime().getTime() - 24 * 60 * 60 * 1000);
	}

	public static Date getYesterdayEndTime() {
		return new Date(getTodayStartTime().getTime() - 1);
	}

	public static Date getEndTime(Date time) {
		Calendar todayEnd = Calendar.getInstance();
		todayEnd.setTime(time);
		todayEnd.set(Calendar.HOUR_OF_DAY, 23);
		todayEnd.set(Calendar.MINUTE, 59);
		todayEnd.set(Calendar.SECOND, 59);
		todayEnd.set(Calendar.MILLISECOND, 999);
		return todayEnd.getTime();
	}

	public static Date getMonthStartTime() {
		Calendar calendar = Calendar.getInstance();
		calendar.set(Calendar.DAY_OF_MONTH, 1);
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);
		return calendar.getTime();
	}

	public static Date getMonthEndTime() {
		Calendar calendar = Calendar.getInstance();
		calendar.add(Calendar.MONTH, 1);
		calendar.set(Calendar.DAY_OF_MONTH, 1);
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);
		return new Date(calendar.getTime().getTime() - 1);
	}

	public static String getMonthStartTime(String pattern) {
		return format(getMonthStartTime(), pattern);
	}

	public static Date getMonthStartTime(Date time) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(time);
		calendar.set(Calendar.DAY_OF_MONTH, 1);
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);
		return calendar.getTime();
	}

	public static String getMonthEndTime(String pattern) {
		return format(getMonthEndTime(), pattern);
	}

	public static Date getBeforeDayTime(int days) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(getTodayStartTime());
		calendar.add(Calendar.DAY_OF_YEAR, -days);

		return calendar.getTime();
	}

	public static Date getBeforeHourTime(Date time, int hour) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(time);
		calendar.add(Calendar.HOUR_OF_DAY, -hour);
		
		return calendar.getTime();
	}

	public static Date getAfterDayTime(Date dateSource, int days) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(dateSource);
		calendar.add(Calendar.DAY_OF_YEAR, days);

		return calendar.getTime();
	}

	public static String getBeforeDayTime(int days, String pattern) {
		return format(getBeforeDayTime(days), pattern);
	}

	public static long getBeforeDayTime(long time, int days) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTimeInMillis(time);
		calendar.add(Calendar.DAY_OF_YEAR, -days);
		return calendar.getTimeInMillis();
	}

	public static Date getBeforeDayTime(Date time, int days) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(time);
		calendar.add(Calendar.DAY_OF_YEAR, -days);
		return calendar.getTime();
	}

	public static String getCurrentTime2String(String pattern) {
		SimpleDateFormat format = new SimpleDateFormat(pattern);
		return format.format(new Date());
	}

	public static String format(Date date, String pattern) {
		SimpleDateFormat format = new SimpleDateFormat(pattern);
		return format.format(date);
	}
	
	public static String format(Long date, String pattern) {
		SimpleDateFormat format = new SimpleDateFormat(pattern);
		return format.format(new Date(date));
	}

	public static Date dateCompute(Date dataSource, int length) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(dataSource);
		calendar.add(Calendar.MONTH, length);
		return calendar.getTime();
	}

	public static Date getTomorrowStartTime() {
		return dateComputeByDay(getTodayStartTime(), 1);
	}

	public static Date getTomorrowEndTime() {
		return dateComputeByDay(getTodayEndTime(), 1);
	}

	public static long getDaysBetween(String startDate, String endDate, String pattern) {
		SimpleDateFormat formatter = new SimpleDateFormat(pattern);
		Long checkday = 0l; // 开始结束相差天数
		try {
			checkday = (formatter.parse(endDate).getTime() - formatter.parse(startDate).getTime())
					/ (1000 * 24 * 60 * 60);
		} catch (ParseException e) {
			e.printStackTrace();
			checkday = null;
		}

		return checkday;
	}
	

	public static String formatTime(long ms) {
		int ss = 1000;
		int mi = ss * 60;
		int hh = mi * 60;
		int dd = hh * 24;
 
        long day = ms / dd;
        long hour = (ms - day * dd) / hh;
        long minute = (ms - day * dd - hour * hh) / mi;
        long second = (ms - day * dd - hour * hh - minute * mi) / ss;
        long milliSecond = ms - day * dd - hour * hh - minute * mi - second * ss;
 
        StringBuilder builder = new StringBuilder();
        if (day > 0) {
        	builder.append(day + "天");
        }
        if (hour > 0) {
        	builder.append(hour + "小时");
        }
        if (minute > 0) {
        	builder.append(minute + "分");
        }
        if (second > 0) {
        	builder.append(second + "秒");
        }
    
        return builder.toString();
   }

	public static long getDaysBetween(Date startDate, Date endDate) {
		Long checkday = 0l; // 开始结束相差天数
		checkday = (endDate.getTime() - startDate.getTime()) / (1000 * 24 * 60 * 60);

		return checkday;
	}

	public static Date getMonthEndTimeByMonthStartTime(Date monthTime) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(monthTime);
		calendar.add(Calendar.MONTH, 1);
		return new Date(calendar.getTimeInMillis() - 1);
	}

	public static long getLastMonthStartTime() {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(getMonthStartTime());
		calendar.add(Calendar.MONTH, -1);

		return calendar.getTimeInMillis();
	}

	public static long setMonth(long time, int num) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTimeInMillis(time);
		calendar.add(Calendar.MONTH, num);
		return calendar.getTimeInMillis();
	}

	public static Date dateComputeByMonth(Date dataSource, int length) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(dataSource);
		calendar.add(Calendar.MONTH, length);
		return calendar.getTime();
	}

	/**
	 * 时间计算器
	 * @param dataSource	时间
	 * @param length
	 * @return
	 */
	public static Date dateComputeByDay(Date dataSource, int length) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(dataSource);
		calendar.add(Calendar.DAY_OF_YEAR, length);
		return calendar.getTime();
	}

	public static Date getBeforeMonthStartTime(int monthDistance) {
		Calendar calendar = Calendar.getInstance();
		calendar.set(Calendar.DAY_OF_MONTH, 1);
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);
		calendar.add(Calendar.MONTH, monthDistance);
		return calendar.getTime();
	}

	public static String isWeekend(long date) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(new Date(date));

		if (cal.get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY) {
			return "周六";
		} else if (cal.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY) {
			return "周日";
		} else {
			return "";
		}
	}

	public static String getWeekday(Date date) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);

		switch (cal.get(Calendar.DAY_OF_WEEK)) {
		case Calendar.MONDAY:
			return "周一";
		case Calendar.TUESDAY:
			return "周二";
		case Calendar.WEDNESDAY:
			return "周三";
		case Calendar.THURSDAY:
			return "周四";
		case Calendar.FRIDAY:
			return "周五";
		case Calendar.SATURDAY:
			return "周六";
		case Calendar.SUNDAY:
			return "周日";
		default:
			return "";
		}
	}

	public static String formatTimeDistance(Date time) {
		long distance = System.currentTimeMillis() - time.getTime();
		long distanceMinute = distance / 60000;

		if (distanceMinute <= 3) {
			return "刚刚";
		} else if (distanceMinute < 60) {
			return distanceMinute + "分钟前";
		} else if (distanceMinute < 60 * 24) {
			return distanceMinute / 60 + "小时前";
		} else if (distanceMinute < 60 * 24 * 30) {
			return distanceMinute / (60 * 24) + "天前";
		} else if (distanceMinute < 60 * 24 * 30 * 12) {
			return distanceMinute / (60 * 24 * 30) + "月前";
		} else {
			return "1年前";
		}
	}

	public static Date getNextMonthFixedDate(Date dataSource, int length, int dayOfMonth) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(dataSource);

		if (calendar.get(Calendar.DAY_OF_MONTH) >= dayOfMonth) {
			length = length + 1;
		}

		calendar.add(Calendar.MONTH, length);
		calendar.set(Calendar.DAY_OF_MONTH, dayOfMonth);
		return calendar.getTime();
	}

	public static boolean isSameMonth(Date date1, Date date2) {
		Calendar c = Calendar.getInstance();
		c.setTime(date1);
		int year1 = c.get(Calendar.YEAR);
		int month1 = c.get(Calendar.MONTH);

		c.setTime(date2);
		int year2 = c.get(Calendar.YEAR);
		int month2 = c.get(Calendar.MONTH);

		return year1 == year2 && month1 == month2;
	}

	public static boolean isToday(Date date) {
		long totayStartTime = DateUtil.getTodayStartTime().getTime();
		long totayEndTime = DateUtil.getTodayEndTime().getTime();

		return date.getTime() >= totayStartTime && date.getTime() <= totayEndTime;
	}

	public static boolean isTodayOrBefore(Date date) {
		long totayEndTime = DateUtil.getTodayEndTime().getTime();

		return date.getTime() <= totayEndTime;
	}

	public static boolean isTomorrow(Date date) {
		long tomorrowStartTime = DateUtil.getTodayStartTime().getTime() + 86400000;
		long tomorrowEndTime = DateUtil.getTodayEndTime().getTime() + 86400000;

		return date.getTime() >= tomorrowStartTime && date.getTime() <= tomorrowEndTime;
	}

	public static boolean isBeforeToday(Date date) {
		long totayStartTime = DateUtil.getTodayStartTime().getTime();

		return date.getTime() < totayStartTime;
	}

	public static int daysBetween(Date smdate, Date bdate) {
		try {
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			smdate = sdf.parse(sdf.format(smdate));
			bdate = sdf.parse(sdf.format(bdate));
			Calendar cal = Calendar.getInstance();
			cal.setTime(smdate);
			long time1 = cal.getTimeInMillis();
			cal.setTime(bdate);
			long time2 = cal.getTimeInMillis();
			long between_days = (time2 - time1) / (1000 * 3600 * 24);
			return Math.abs(Integer.parseInt(String.valueOf(between_days)));
		} catch (Exception e) {
			e.printStackTrace();
			return 0;
		}
	}

	public static Date getYearStartTime() {
		Calendar calendar = Calendar.getInstance();
		calendar.set(Calendar.DAY_OF_MONTH, 1);
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);
		calendar.set(Calendar.MONTH, 0);
		return calendar.getTime();
	}

	public static Date getYearEndTime() {
		Calendar calendar = Calendar.getInstance();
		calendar.set(Calendar.DAY_OF_MONTH, 31);
		calendar.set(Calendar.HOUR_OF_DAY, 23);
		calendar.set(Calendar.MINUTE, 59);
		calendar.set(Calendar.SECOND, 59);
		calendar.set(Calendar.MILLISECOND, 999);
		calendar.set(Calendar.MONTH, 11);
		return calendar.getTime();
	}

	public static Date getYearStartTime(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.set(Calendar.DAY_OF_MONTH, 1);
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);
		calendar.set(Calendar.MONTH, 0);
		calendar.set(Calendar.YEAR, calendar.get(Calendar.YEAR));
		return calendar.getTime();
	}

	public static Date getYearEndTime(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.set(Calendar.DAY_OF_MONTH, 31);
		calendar.set(Calendar.HOUR_OF_DAY, 23);
		calendar.set(Calendar.MINUTE, 59);
		calendar.set(Calendar.SECOND, 59);
		calendar.set(Calendar.MILLISECOND, 999);
		calendar.set(Calendar.MONTH, 11);
		calendar.set(Calendar.YEAR, calendar.get(Calendar.YEAR));
		return calendar.getTime();
	}

	public static Date getBeforeYearTime(Date date, int year) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(Calendar.YEAR, -year);
		return calendar.getTime();
	}

	public static Date getBeforeYearTimeStart(Date date, int year) {
		return getYearStartTime(getBeforeYearTime(date, year));
	}

	public static Date getBeforeYearTimeEnd(Date date, int year) {
		return getYearEndTime(getBeforeYearTime(date, year));
	}

	public static Date getBeforeMonthStartTime(Date date, int monthDistance) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.set(Calendar.DAY_OF_MONTH, 1);
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);
		calendar.add(Calendar.MONTH, monthDistance);
		calendar.set(Calendar.YEAR, calendar.get(Calendar.YEAR));
		return calendar.getTime();
	}
	
	public static Date getBeforeMonth(Date date, int monthDistance) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);
		calendar.add(Calendar.MONTH, -monthDistance);
		calendar.set(Calendar.YEAR, calendar.get(Calendar.YEAR));
		return calendar.getTime();
	}

	public static int dayBetween(Date endTime, Date startTime) {
		return (int) ((endTime.getTime() - startTime.getTime()) / (1000 * 60 * 60 * 24));
	}

	public static Date getBeforeSecondTime(Date date, int secondDistance) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(Calendar.SECOND, secondDistance);
		return calendar.getTime();
	}

	public static Date getBeforeMinutesTime(Date date, int secondDistance) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(Calendar.SECOND, -secondDistance * 60);
		return calendar.getTime();
	}

	public static Date str2Date(String str, Locale locale, String pattern) {
		if (StringUtils.isBlank(str))
			return null;
		
		Date date = null;
		try {
			SimpleDateFormat format = new SimpleDateFormat(pattern, locale);
			date = format.parse(str);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return date;
	}


	// 七日走向使用  转换时间   时间转成月日
	public static String dateFormat(Date date){
		String temp = DateUtil.format(date,"MM.dd");
		if (temp.substring(0,1).equals("0")){
			return temp.substring(1,5);
		}else {
			return temp;
		}
	}
	
	public static long getToDayLeft(){
		Date end = getTodayStartTime();
		return end.getTime() - new Date().getTime();
	}
	
	
	public static long getThatDayLeft(Date date){
		Date end = getEndTime(date);
		return end.getTime() - date.getTime();
	}
	
	public static long getCloseWholeLeft(Date date){
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		boolean need = calendar.get(Calendar.MINUTE) != 0 ||  calendar.get(Calendar.SECOND) != 0
				|| calendar.get(Calendar.MILLISECOND) != 0;
		if(!need) return date.getTime();
		calendar.add(Calendar.HOUR_OF_DAY, 1);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.MILLISECOND, 0);
		return calendar.getTimeInMillis();
	}

	/**
	 * 格式化UTC时间
	 * @param date
	 * @return
	 */
	public static Date formatUTC(String date){
		// 例如
//		String date = "2018-02-28T00:00:00Z";

		Date temp = null;
		SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
//		df.setTimeZone(TimeZone.getTimeZone("UTC"));
		try {
			temp = df.parse(date);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return temp;
	}
	
	public static void main(String[] args) {
//		SimpleDateFormat dateFormat = new SimpleDateFormat("MMM d, yyyy", Locale.ENGLISH);
//		try {
//			Date openTime = dateFormat.parse("Apr 28, 2013");
//			System.out.println(openTime);
//		} catch (ParseException e) {
//			e.printStackTrace();
//		}
//		long a = 1532050200;
//		SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//这个是你要转成后的时间的格式
//		String sd = sdf.format(new Date(a * 1000));   // 时间戳转换成时间
//		System.out.println(sd);//打印出你要的时间

//		System.out.println(new Date(1535871600000l));
//		System.out.println(DateUtil.getBeforeDayTime(0));

		String aaa = "2018-02-28T00:00:00Z";
		//System.out.println(DateUtil.dateComputeByDay(new Date(),1));
		//System.out.println(new Date());
		//System.out.println(DateUtil.dateComputeByDay(new Date(),-1));
		
		Date e = new Date();
		System.out.println(new Date(1539932400000l));
	}

}
